<template>
  <div class="table-base">
    <el-table
      v-loading="props.loading"
      :data="props.tableData"
      style="width: 100%"
      row-key="id"
      border
      @selection-change="handleSelectionChange"
    >
      <el-table-column v-if="props.isShowSelectionCol" type="selection" width="46" />
      <el-table-column v-if="props.isShowIndexCol" type="index" label="序号" align="center" width="80" />
      <template v-for="column in props.columns" :key="column.prop">
        <template v-if="column.slotName">
          <el-table-column v-bind="column" :align="column.align ?? 'center'">
            <template #default="scope">
              <slot :name="column.slotName" v-bind="scope"></slot>
            </template>
          </el-table-column>
        </template>
        <template v-else>
          <el-table-column v-bind="column" :align="column.align ?? 'center'" />
        </template>
      </template>
    </el-table>
    <div v-if="props.total > 0" class="pagination">
      <el-pagination
        :current-page="props.pageIndex"
        :page-size="props.pageSize"
        :page-sizes="[10, 20, 50]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="props.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script setup lang="ts" generic="T">
interface Props {
  tableData: T[] // 表格数据
  columns: Column[] // 表格列
  loading?: boolean // 请求数据时的 loading
  pageIndex?: number // 当前页数
  pageSize?: number // 每页显示条数
  total?: number // 总条数
  isShowIndexCol?: boolean // 是否显示索引列，默认显示
  isShowSelectionCol?: boolean // 是否显示多选框，默认显示
}

const props = withDefaults(defineProps<Props>(), {
  loading: false,
  total: 0,
  isShowIndexCol: true,
  isShowSelectionCol: true
})

const emit = defineEmits<{
  pageChange: [pageIndex: number, pageSize: number]
  selectionChange: [val: T[]]
}>()

defineSlots<{
  [key: string]: (scope: { row: T; $index: number; column: Column }) => any
}>()

/**
 * 每页显示条数改变
 *
 * @param pageSize 每页显示条数
 */
const handleSizeChange = (pageSize: number) => {
  emit("pageChange", props.pageIndex!, pageSize)
}

/**
 * 当前页数改变
 *
 * @param pageIndex 当前页数
 */
const handleCurrentChange = (pageIndex: number) => {
  emit("pageChange", pageIndex, props.pageSize!)
}

/**
 * 选择项改变
 *
 * @param val 选择项
 */
const handleSelectionChange = (val: T[]) => {
  emit("selectionChange", val)
}
</script>

<style lang="scss" scoped>
.table-base {
  :deep(.el-table) {
    --el-table-header-bg-color: #eff1fe;
    --el-table-border-color: var(--color-border-primary);
    --el-table-header-text-color: var(--color-black);
    --el-table-text-color: var(--color-black);

    thead th {
      font-weight: normal;
    }
  }

  .pagination {
    margin-top: 20px;

    :deep(.el-pagination) {
      justify-content: flex-end;
    }
  }
}
</style>
